﻿package framework 
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.utils.getTimer;
	
	/**
	 * 計時器
	 * @author fly
	 */
	public class Timepiece 
	{
		private var _frameFun:Array = null;				// 帧方法
		private var _timerFun:Array = null;				// 计时
		private var _delayFun:Array = null;				// 延时回调（1次）
		private var _running:Boolean = false;
		private var _stage:Stage = null;
		private var _lasttime:int = 0;
		
		static public const FRAME:int = 0;				// 帧方法
		static public const TIMER:int = 1;				// 计时
		static public const DELAY:int = 2;				// 延时回调（1次）
		
		/**
		 * 构造
		 */
		public function Timepiece(single:Single) 
		{
			_frameFun = new Array();
			_timerFun = new Array();
			_delayFun = new Array();
		}
		
		/**
		 *  初始化舞台
		 * @param	s
		 */
		public function initStage(s:Stage):void
		{
			_stage = s;
		}
		
		/**
		 *  帧
		 * @param	fun
		 */
		public function addFun(fun:Function):void
		{
			_frameFun.push(fun);
			if (!_running)
				start();
		}
		
		/**
		 *  延时
		 * @param	fun
		 * @param	time
		 */
		public function addTimerFun(fun:Function, time:uint):void
		{
			_timerFun.push([fun, time, getTimer()]);
			if (!_running)
				start();
		}
		
		/**
		 *  延时（1次）
		 * @param	fun
		 * @param	time
		 */
		public function addDelayCall(fun:Function, time:uint):void
		{
			_delayFun.push([fun, time, getTimer()]);
			if (!_running)
				start();
		}
		
		/**
		 * 刪除計時器type=1 ENTER_FRAME TYPE=0 回調函數=2
		 * @param	fun
		 * @param	type
		 */
		public function removeFun(fun:Function , type:int = 0):void
		{
			if (type == FRAME)
			{
				for (var i:int = 0; i < _frameFun.length; i++) 
				{
					if (_frameFun[i] == fun)
					{
						_frameFun.splice(i, 1);
						break;
					}
				}
			}
			else if (type == TIMER)
			{
				for (var j:int = 0; j < _timerFun.length; j++) 
				{
					if (_timerFun[j][0] == fun)
					{
						_timerFun.splice(j, 1);
						break;
					}
				}
			}
			else
			{
				for (var h:int = 0; h < _delayFun.length; h++) 
				{
					if (_delayFun[h][0] == fun)
					{
						_delayFun.splice(h, 1);
						break;
					}
				}
			}
			if (_timerFun.length == 0 && _frameFun.length == 0 && _delayFun.length == 0)
				stop();
		}
		
		private function start():void
		{
			_running = true;
			_stage.addEventListener(Event.ENTER_FRAME , timerHandler , false, 0, true);
			_lasttime = getTimer();
		}
		
		private function stop():void
		{
			_running = false;
			_stage.removeEventListener(Event.ENTER_FRAME , timerHandler, false);
		}
		
		private function runFrameFun():void
		{
			var temp:Array = _frameFun.concat();
			var length:int = _frameFun.length;
			var i:int = 0;
			for (i = 0; i < length; i++) 
			{
				var fun:Function = temp[i];
				if (fun != null)
					fun();
			}
		}
		
		// 运行
		private function timerHandler(event:Event):void 
		{
			var length:int = 0;
			var temp:Array = [];
			var i:int = 0;
			var time:int = getTimer();
			length = (time - _lasttime) / 30;
			_lasttime = time;
			length = length == 0?1:length;
			for (i = 0; i < length; i++) 
			{
				runFrameFun();
			}
			length = _timerFun.length;
			temp = _timerFun.concat();
			for (i = 0; i < length; i++) 
			{
				var arr:Array = temp[i];
				var fun1:Function = arr[0];
				
				if (fun1 != null)
				{
					if (time - arr[2] >= arr[1])
					{
						arr[2] += arr[1];
						fun1();
					}
				}
			}
			length = _delayFun.length;
			//trace("333:::::  " + length);
			for (i = 0; i < length; i++)
			{
				var arr1:Array = _delayFun[i];
				if (arr1 == null)
					continue;
				var fun2:Function = arr1[0];
				 
				if (fun2 != null)
				{
					if (time - arr1[2] >= arr1[1])
					{
						_delayFun.splice(i, 1);
						i--;
						length--;
						fun2();
					}
				}
			}
		}
		
		/**
		 * 单例引用
		 */
		public static function get instance():Timepiece
		{
			if(_instance == null)
			{
				_instance = new Timepiece(new Single());
			}
			return _instance;
		}
		
		private static var _instance:Timepiece = null;
	}
}
class Single{}